#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <atomic>
using namespace std;



void Print(int n, int& x, mutex& mtx)
{
	for (int val = 0; val < n; ++val)
	{
		mtx.lock();
		cout << this_thread::get_id() << ":" << val << endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
		++x;
		mtx.unlock();
	}
}
//
//int main()
//{
//	mutex m;
//	int count = 0;
//	thread t1(Print, 10, ref(count), ref(m));
//	thread t2(Print, 10, ref(count), ref(m));
//
//	t1.join();
//	t2.join();
//	cout << count << endl;
//	return 0;
//}



//int main()
//{
//	mutex mtx;
//	int x = 0;
//	int n = 10;
//	thread t1([&](){
//		for (int val = 0; val < n; ++val)
//		{
//			mtx.lock();
//			cout << this_thread::get_id() << ":" << val << endl;
//			std::this_thread::sleep_for(std::chrono::milliseconds(100));
//			++x;
//			mtx.unlock();
//		}
//	});
//
//	thread t2([&](){
//		for (int val = 0; val < n; ++val)
//		{
//			mtx.lock();
//			cout << this_thread::get_id() << ":" << val << endl;
//			std::this_thread::sleep_for(std::chrono::milliseconds(100));
//			++x;
//			mtx.unlock();
//		}
//	});
//
//	t1.join();
//	t2.join();
//	cout << x << endl;
//	return 0;
//}
//
////int main()
////{
////	mutex mtx;
////	int x = 0;
////	int n = 10;
////	int m;
////	cin >> m;
////
////	vector<thread> v(m);
////	//v.resize(m);
////
////	for (int val = 0; val < m; ++val)
////	{
////		// 移动赋值给vector中线程对象
////		v[val] = thread([&](){
////			for (int val = 0; val < n; ++val)
////			{
////				mtx.lock();
////
////				cout << this_thread::get_id() << ":" << val << endl;
////				std::this_thread::sleep_for(std::chrono::milliseconds(100));
////				++x;
////
////				mtx.unlock();
////			}
////		});
////	}
////
////	for (auto& t : v)
////	{
////		t.join();
////	}
////
////	cout << x << endl;
////
////	return 0;
////}
//
//
////int main()
////{
////	mutex mtx;
////	int x = 0;
////	int n = 1000000;
////	int m;
////	cin >> m;
////
////	vector<thread> v(m);
////	for (int val = 0; val < m; ++val)
////	{
////		// 移动赋值给vector中线程对象
////		v[val] = thread([&](){
////			for (int val = 0; val < n; ++val)
////			{
////				// 并行
////				mtx.lock();
////				++x;
////				mtx.unlock();
////			}
////		});
////
////		//v[val] = thread([&](){
////		//	// 串行
////		//	mtx.lock();
////		//	for (int val = 0; val < n; ++val)
////		//	{
////		//		++x;
////		//	}
////		//	mtx.unlock();
////		//});
////	}
////
////	for (auto& t : v)
////	{
////		t.join();
////	}
////
////	cout << x << endl;
////
////	return 0;
////}
//
//
////int main()
////{
////	mutex mtx;
////	atomic<int> x = 0;
////	//int x = 0;
////	int n = 1000000;
////	int m;
////	cin >> m;
////
////	vector<thread> v(m);
////	for (int val = 0; val < m; ++val)
////	{
////		// 移动赋值给vector中线程对象
////		v[val] = thread([&](){
////			for (int val = 0; val < n; ++val)
////			{
////				// t1 t2 t3 t4
////				++x;
////			}
////		});
////	}
////
////	for (auto& t : v)
////	{
////		t.join();
////	}
////
////	cout << x << endl;
////
////	return 0;
////}
//
//int main()
//{
//	mutex mtx;
//	int x = 0;
//	int n = 10;
//	int m;
//	cin >> m;
//
//	vector<thread> v(m);
//	//v.resize(m);
//
//	for (int val = 0; val < m; ++val)
//	{
//		// 移动赋值给vector中线程对象
//		v[val] = thread([&](){
//			for (int val = 0; val < n; ++val)
//			{
//				mtx.lock();
//
//				cout << this_thread::get_id() << ":" << val << endl;
//				std::this_thread::sleep_for(std::chrono::milliseconds(100));
//				++x;
//
//				mtx.unlock();
//			}
//		});
//	}
//
//	for (auto& t : v)
//	{
//		t.join();
//	}
//
//	cout << x << endl;
//
//	return 0;
//}


//int main()
//{
//	mutex mtx;
//	 int x = 0;
//	//atomic<int> x = 0;
//	int n = 100000;
//	int m = 2;
//	vector<thread> v(m);
//	for (int i = 0; i < m; ++i)
//	{
//		// 移动赋值给vector中线程对象
//		v[i] = thread([&](){
//			for (int i = 0; i < n; ++i)
//			{
//				//lock_guard<mutex> lk(mtx);
//				++x;
//			}
//		});
//	}
//	for (auto& t : v)
//	{
//		t.join();
//	}
//	cout << x << endl;
//	return 0;
//}
////
//



//
//
//int main()
//{
//	int val = 0;
//	int n = 10; // 打印的范围
//	mutex mtx; // 创建互斥锁
//	condition_variable cond; // 创建条件变量
//
//	thread t1([&](){
//		while (val < n)
//		{
//			unique_lock<mutex> lock(mtx); // 加锁
//			while (val % 2 == 0)// 判断是否是偶数
//			{
//				// 是偶数则放入等待队列中等待
//				cond.wait(lock);
//			}
//			// 是奇数时打印
//			cout << "thread1:" << this_thread::get_id() << "->" << val++ << endl;
//			cond.notify_one(); // 唤醒等待队列中的一个线程去打印偶数
//		}
//	});
//
//	this_thread::sleep_for(chrono::microseconds(100));
//
//	thread t2([&](){
//		while (val < n)
//		{
//			unique_lock<mutex> lock(mtx);
//			while (val % 2 == 1)
//			{
//				cond.wait(lock);
//			}
//			cout << "thread2:" << this_thread::get_id() << "->" << val++ << endl;
//			cond.notify_one();//唤醒等待队列中的一个线程去打印奇数
//		}
//	});
//
//	t1.join();
//	t2.join();
//
//	return 0;
//}


int main()
{
	int val = 0;
	int n = 10; // 打印值的范围
	mutex mtx;
	condition_variable cond;
	bool ready = true;

	// t1线程打印奇数
	thread t1([&](){
		while (val < n)
		{
			{
				unique_lock<mutex> lock(mtx);
				cond.wait(lock, [&ready](){return !ready; });

				cout << "thread1:" << this_thread::get_id() << "->" << val << endl;
				val += 1;

				ready = true;

				cond.notify_one();
			}

			//this_thread::yield();
			this_thread::sleep_for(chrono::microseconds(10));
		}
	});

	// t2线程打印偶数
	thread t2([&]() {
		while (val < n)
		{
			unique_lock<mutex> lock(mtx);
			cond.wait(lock, [&ready](){return ready; });

			cout << "thread2:" << this_thread::get_id() << "->" << val << endl;
			val += 1;
			ready = false;

			cond.notify_one();
		}
	});

	t1.join();
	t2.join();

	return 0;
}